//==================================================================
/// particler.cpp
///
/// Created by Davide Pasca - 2009/10/5
/// See the file "license.txt" that comes with this project for
/// copyright info. 
//==================================================================

#include "stdafx.h"
#include "particler.h"

//==================================================================
particler::particler( transformer *pXFormer )
{
	mParts.resize( MAX_PARTS );

	mActiveN = 0;
	mpXFormer = pXFormer;
	mActive	= false;

	mpSptr = NULL;
}

//==================================================================
void particler::begin(
			float crea_speed,
			int lifespan,
			const Vec3 &t0Speed,
			const Vec3 &t0RandSize,
			const Vec3 &randSize1,
			const Vec3 &randSize2,
			const Vec3 &atten,
			sprite *pSptr )
{
	_crea_speed = crea_speed;
	_lifespan = lifespan;

	mActive = true;

	mActiveN = 0;

	for (int i=0; i < MAX_PARTS; ++i)
	{
		mParts[i].life = 0;
		mParts[i].flags = 0;
	}

	mT0Speed	=	t0Speed		;
	mT0RandSize	=	t0RandSize	;
	mRandSize1	=	randSize1	;
	mRandSize2	=	randSize2	;
	mAtten		=	atten		;

	mpSptr = pSptr;
}

float particler::rand_range( float x1, float x2 )
{
	float	tf;

	tf = (float)Math::Random();
	return tf * x1 + (1.0f - tf) * x2;
}

void particler::idle( float px, float py, float pz, float vx, float vy, float vz )
{
	int	i, ii;
	int	to_create;
	float	t0_hsiz_x, t0_hsiz_y, t0_hsiz_z;

	if ( mActive == false )
		to_create = 0;
	else
	{
		_crea_cnt += _crea_speed; 
		to_create = (int)_crea_cnt;	
		_crea_cnt -= to_create;
	}

	if ( to_create <= 0 && mActiveN <= 0 )
		return;

	t0_hsiz_x = mT0RandSize.x * 0.5f;
	t0_hsiz_y = mT0RandSize.y * 0.5f;
	t0_hsiz_z = mT0RandSize.z * 0.5f;
	for (i=0; i < MAX_PARTS; ++i)
	{
		if ( (mParts[i].flags & 1) == 0 )
		{
			if ( to_create > 0 )
			{
				mParts[i].flags = 1;
				mParts[i].life = _lifespan;

				mParts[i].pos.x = px + t0_hsiz_x - (float)Math::Random() * mT0RandSize.x;
				mParts[i].pos.y = py + t0_hsiz_y - (float)Math::Random() * mT0RandSize.y;
				mParts[i].pos.z = pz + t0_hsiz_z - (float)Math::Random() * mT0RandSize.z;

				mParts[i].vel.x = mT0Speed.x + rand_range( mRandSize1.x, mRandSize2.x );
				mParts[i].vel.y = mT0Speed.y + rand_range( mRandSize1.y, mRandSize2.y );
				mParts[i].vel.z = mT0Speed.z + rand_range( mRandSize1.z, mRandSize2.z );

				++mActiveN;
				--to_create;
			}
		}
		else
		{
			ii = i * DATA_SIZE;
			if ( mParts[i].life > 0 )
			{
				if ( --mParts[i].life <= 0 )
				{
					mParts[i].flags = 0;
					--mActiveN;
				}
				else
				{
					mParts[i].pos.x += mParts[i].vel.x + vx;
					mParts[i].pos.y += mParts[i].vel.y + vy;
					mParts[i].pos.z += mParts[i].vel.z + vz;

					mParts[i].vel.x *= mAtten.x;
					mParts[i].vel.y *= mAtten.y;
					mParts[i].vel.z *= mAtten.z;
				}
			}
		}
	}
}

void particler::draw( graphics &g )
{
	for (int i=0; i < MAX_PARTS; ++i)
	{
		int ii = i * DATA_SIZE;
		if ( (mParts[i].flags & 1) == 1 )
		{
			float zz = mpXFormer->xform_zf( mParts[i].pos.z );
			if ( mpXFormer->_clip_flags == 0 )
			{
				int sx = mpXFormer->xform_xf( mParts[i].pos.x );
				int sy = mpXFormer->xform_yf( mParts[i].pos.y );

				//System.out.println( "sx="+sx+" sy="+sy );
				//g.line_h( sx, sx+2, sy, 0xffffff );
				mpSptr->draw( g, 0, sx, sy, zz, sprite::TRANS100_100_FLG );
			}
		}
	}
}

void particler::end()
{
	mActive = false;
}